package com.wtao.imagereader.aicamera;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.graphics.Typeface;
import android.graphics.YuvImage;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.util.Range;
import android.util.Size;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import com.wtao.imagereader.AutoApplication;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 2023-12-1
 * 之前有车外摄像头延时录视频(抽帧录视频)， 后面去除了延时录视频功能（就不需要用VideoEncoder2封装的MediaCodec来编码视频数据了，有个bug没解决，编码生成的视频底部有绿条）
 * 普通录制视频可以换成MediaRecorder来解决这个录制视频绿条问题
 */
public class CameraV2Manager implements ImageReader.OnImageAvailableListener {
    public static final String TAG = "CameraV2Manager";

    public static int MSG_ID_UPDATE_TIME = 99;
    private static CameraV2Manager mInstance;
    private CameraV2Proxy cameraV2Proxy;
    private boolean mFlagTakePhoto = false;

    private boolean dvrRecoding = false;
    private int divFrame = 0;
    private int divRate = 10;

    private long startRecordTime = 0;

    private int recordTime = 0;//录制时间
    private long targetTotalTimeSeconds = 60;//录像界面顶部的1min 3min,5min是录制视频的最大时长，到了时间自动停止录，中途可以手动停止录
    //更新显示录制的时间
    Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == MSG_ID_UPDATE_TIME) {
                recordTime++;
                 if (recordTime >= targetTotalTimeSeconds) {
                    if (CameraV2Manager.getInstance().isRecordingVideo()) {
                       // EventBus.getDefault().post(new RecordSaveEvent());
                    } else {
                        handler.sendEmptyMessageDelayed(MSG_ID_UPDATE_TIME, 1000);
                    }
                } else {
                    handler.sendEmptyMessageDelayed(MSG_ID_UPDATE_TIME, 1000);
                }
            }
        }
    };

    public void setTargetTotalTimeSeconds(long targetTotalTimeSeconds) {
        this.targetTotalTimeSeconds = targetTotalTimeSeconds;
    }


    private CameraV2Manager() {
        cameraV2Proxy = new CameraV2Proxy(AutoApplication.getContext());
        cameraV2Proxy.startCameraThread();
     }

    public void setupCamera(){
        cameraV2Proxy.setupCamera();
    }

    public static CameraV2Manager getInstance() {
        if (mInstance == null) {
            synchronized (CameraV2Manager.class) {
                if (mInstance == null) {
                    mInstance = new CameraV2Manager();
                }
            }
        }
        return mInstance;
    }

    public void setFailedCallback(CameraV2Proxy.FailedCallback callback){
        cameraV2Proxy.setFailedCallback(callback);
    }

    public void setCameraId(String cameraId) {
        if (cameraV2Proxy != null) {
            cameraV2Proxy.setCameraId(cameraId);
        }
    }

    public void capture() {
        mFlagTakePhoto = true;
    }

    public String getCurrentCameraId() {
        if (cameraV2Proxy != null) {
            return cameraV2Proxy.getCurrentCameraId();
        }
        return null;
    }

    public void setPreviewSize(int width, int height) {
        if (cameraV2Proxy != null) {
            cameraV2Proxy.setPreviewSize(width, height);
            Log.e(TAG, "setPreviewSize：width="+width+" height="+height);
        }
    }

    public void openCamera(SurfaceTexture surfaceTexture){
        Log.e(TAG, "openCamera start");
        cameraV2Proxy.setCallback(new CameraV2Proxy.CameraStateCallback() {
            @Override
            public void onOpened() {
                CameraDevice cameraDevice = cameraV2Proxy.getCameraDevice();
                cameraV2Proxy.startPreview(cameraDevice);
            }

            @Override
            public void onError() {
                super.onError();

            }
        });
        cameraV2Proxy.setPreviewSize(1920,1080);
        cameraV2Proxy.setPreview(surfaceTexture, CameraV2Manager.this);
        boolean flag = cameraV2Proxy.openCamera();
        Log.e(TAG,"openCamera:"+flag  );
    }

    public void closeCamera(){
        //if(!dvrRecoding){
            cameraV2Proxy.releaseCamera();
        //}
    }

    public void switchCamera(String cameraID) {
        Log.e(TAG, "switchCamera(String cameraID) cameraID="+cameraID);
        closeCamera();
        Log.e(TAG, "closeCamera closePreviewSession");

        cameraV2Proxy.setCameraId(cameraID);
        if(cameraV2Proxy.getSurfaceTexture() != null){
            openCamera(cameraV2Proxy.getSurfaceTexture());
        }

    }

    public boolean isRecordingVideo(){

        return false;
    }

    public void setDvrRecordRate(int rate){
        this.divRate = rate;
    }

    public void startRecord() {
        //顶部有个录制的时间
        startRecordTime = System.currentTimeMillis();
        Log.e(TAG, "getCurrentCameraId()="+getCurrentCameraId());

        recordTime = 0;
        handler.sendEmptyMessageDelayed(MSG_ID_UPDATE_TIME, 1000);
    }

    public long getStartRecordTime() {
        return startRecordTime;
    }

    //点击了停止录视频，或者录制视频到了特定时长调用
    public void stopRecord() {
        handler.removeMessages(MSG_ID_UPDATE_TIME);

    }

    @Override
    public void onImageAvailable(ImageReader reader) {
        //Log.e(TAG, "onImageAvailable");
        cameraV2Proxy.getCameraHandler().post(new ImageTask(reader));
    }

    private class ImageTask implements Runnable{
        private ImageReader reader;
        public ImageTask(ImageReader reader){
            this.reader = reader;
        }
        @Override
        public void run() {
            if(cameraV2Proxy.getCameraDevice() == null) return;
            Image image = reader.acquireLatestImage();
            if (image == null) {
                return;
            }

            image.close();
        }
    }

    //图片保存到特定目录
    private void saveImage(byte[] data,int width,int height) {
        //这是在onImageAvailable里做的，是在子线程执行的代码
        Log.e(TAG, "拍照保存图片 saveImage(Image image)");


    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void drawWaterMask(Bitmap bitmap, int width, int height){

    }

    private String getWeek(int week){
        switch (week){
            case 1:
                return "星期日";
            case 2:
                return "星期一";
            case 3:
                return "星期二";
            case 4:
                return "星期三";
            case 5:
                return  "星期四";
            case 6:
                return  "星期五";
            case 7:
                return "星期六";
        }
        return "";
    }

    public void getCameraInfo() {
        CameraManager cameraManager = (CameraManager) AutoApplication.getContext().getSystemService(Context.CAMERA_SERVICE);
        try {
            String[] cameraIds = cameraManager.getCameraIdList();
            Log.e(TAG, "cameraIds.length=" + cameraIds.length);
            for (String cameraId : cameraIds) {
                CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
                StreamConfigurationMap configMap = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                Size[] sizes = configMap.getOutputSizes(SurfaceTexture.class);
                Log.e(TAG, "cameraId=" + cameraId);
                // 打印输出所有这个摄像头支持分辨率信息
                for (Size size : sizes) {
                    Log.e(TAG, "getCameraInfo() Camera " + cameraId + " supported resolution: " + size.getWidth() + "x" + size.getHeight());
                }
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    public String getCurrentVideoPath() {
        //return mCurrentVideoPath;
        return cameraV2Proxy.getVideoSavePath();
    }

    private int getCameraFrameRate(String cameraId) {
        CameraManager cameraManager = (CameraManager) AutoApplication.getContext().getSystemService(Context.CAMERA_SERVICE);
        try {
            CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
            Range<Integer> fpsRange = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES)[0];
            int minFps = fpsRange.getLower();
            int maxFps = fpsRange.getUpper();
            Log.d(TAG, "摄像机帧率范围：" + minFps + " - " + maxFps);
            return (minFps + maxFps) / 2;
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        return 25;
    }
}
